#pragma once
#include<iostream>
#include<assert.h>
#include"iterator.h"
using std::cout;
using std::endl;
using my_iterator::ReverseIterator;
namespace my_list
{
	//节点类
	template<class T>
	struct list_node//默认访问权限是public，不对成员的访问限制
	{
		list_node<T>* _next;
		list_node<T>* _prev;
		T _data;

		list_node(const T& x=T())//匿名对象做缺省值，T需要默认构造
			:_next(nullptr), _data(x), _prev(nullptr)
		{
		}
	};

	//迭代器是原生指针或者是自定义类型
	//普通迭代器类
	template<class T,class Ref,class Ptr>
	//Ref与Ptr是为了适用常量迭代器,Ref=T&	Ptr=T*
	struct __list_iterator
	{
		typedef list_node<T> node;
		typedef __list_iterator<T,Ref,Ptr> self;//类对象本身
		node* _node;

		__list_iterator(node* n)//迭代器初始化
			:_node(n)
		{}

		Ref operator* ()
		//常量迭代器与普通迭代器只有返回值不同
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}

		self& operator++()//返回迭代器类对象
		{
			_node = _node->_next;
			return *this;
		}
		self& operator++(int)//int只用于标识后置++
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self& operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		bool operator!=(const self& li)
		{
			return _node != li._node;
		}
		bool operator==(const self& li)
		{
			return _node == li._node;
		}
	};
	////反向迭代器类
	//template<class Iterator,class Ref,class Ptr>
	//struct ReverseIterator
	//{
	//	typedef ReverseIterator<Iterator,Ref,Ptr> Self;
	//	Iterator _cur;

	//	ReverseIterator(Iterator it)
	//		:_cur(it)
	//	{

	//	}

	//	Self& operator++()
	//	{
	//		--_cur;
	//		return *this;
	//	}

	//	Self& operator++(int)
	//	{
	//		--_cur;
	//		return *this;
	//	}

	//	Self& operator--()
	//	{
	//		++_cur;
	//		return *this;
	//	}

	//	Self& operator--(int)
	//	{
	//		++_cur;
	//		return *this;
	//	}

	//	bool operator!=(const Self& s)
	//	{
	//		return _cur != s._cur;
	//	}
	//};

	//链表类
	template<class T>
	class list
	{
		typedef list_node<T> node;//节点
	public:
		typedef __list_iterator<T,T&,T*> iterator;//普通迭代器
		typedef __list_iterator<T, const T&,const T*> const_iterator;//常量迭代器
		//typedef __list_const_iterator<T> const_iterator;//常量迭代器
		typedef ReverseIterator<iterator, T&, T*>reverse_iterator;//反向迭代器
		typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;//反向迭代器
		void empty_init()
		{
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		list()
		{
			empty_init();
		}
		template<class Iterator>
		list(Iterator first, Iterator last)
		{
			empty_init();//空初始化
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		void swap(list<T>& tmp)//套用std库中的swap方便实现拷贝
		{
			std::swap(_head, tmp._head);
		}
		list(const list<T>& cst)//拷贝构造
		{
			empty_init();
			list<T> tmp(cst.begin(), cst.end());
			swap(tmp);
		}
		list<T>& operator=(list<T> lt)//赋值构造
		//如果引用传参会导致拷贝
		{
			swap(lt);
			return *this;
		}
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}



		//迭代器
		iterator begin() { return iterator(_head->_next); }//匿名构造迭代器对象
		const_iterator begin()const { return const_iterator(_head->_next); }
		iterator end() { return iterator(_head); }
		const_iterator end()const { return const_iterator(_head); }
		reverse_iterator rbegin () { return reverse_iterator(end()); }
		reverse_iterator rend() { return reverse_iterator(begin()); }
		//reverse_iterator rbegin() { return reverse_iterator(_head->_prev); }
		//reverse_iterator rend() { return reverse_iterator(_head); }


		//增删查改
		void push_back(const T& x)
		{
			node* tail = _head->_prev;
			node* newnode = new node(x);
			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
			newnode->_data = x;
		}
		//void push_back(const T& x)
		//{
		//	insert(end(), x);
		//}
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		void pop_back()
		{
			erase(--end());
		}
		void insert(iterator pos,const T& x)
		{
			node* cur = pos._node;
			node* prev = cur->_prev;

			node* new_node = new node();

			prev->_next = new_node;
			new_node->_prev = prev;
			new_node->_next = cur;
			cur->_prev = new_node;
			new_node->_data = x;
		}

		iterator erase(iterator pos)
		{
			assert(pos != end());
			node* prev = pos._node->_prev;
			node* next = pos._node->_next;

			prev->_next = next;
			next->_prev = prev;
			delete pos._node;

			return iterator(next);
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it=erase(it);
			}
		}
	private:
		node* _head;//哨兵位，不含数据
	};




	template<typename T>
	void show(const list<T>& ls)
	{
		//auto it = ls.begin();
		//while (it != ls.end())
		//{
		//	cout << *it << " ";
		//	++it;
		//}
		//cout << endl;
		for (auto ch : ls)
		{
			cout << ch << " ";
		}
		cout << endl;
	}


	void test_1()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		show(l1);

		const list<int> lt1;
		//const对象在定义的时候是不具有const属性的，否则无法进行初始化

		list<int> l2;
		l2 = l1;
		show(l2);

		list<int> l3 = l1;
		show(l3);
	}



	struct test_A
	{
		int _a1;
		int _a2;
		test_A(int a1=0, int a2=0)
			:_a1(a1), _a2(a2)
		{}
	};


	void test_2()
	{
		list<test_A> lt;//指定内部为自定义类型
		lt.push_back(test_A(1, 1));
		lt.push_back(test_A(2, 2));
		lt.push_back(test_A(3, 3));

		list<test_A>::iterator it = lt.begin();
		while (it != lt.end())
		{
			//cout << (*it)._a1 << " ";
			cout << it->_a1 << " " << it->_a2 <<endl;
			it++;
		}
		cout << endl;
	}

	void test_3()
	{
		list<test_A> lt;
		lt.push_back(test_A(1, 1));
		lt.push_back(test_A(2, 2));
		lt.push_back(test_A(3, 3));

		lt.insert(lt.begin(), test_A(5,5));
		list<test_A>::iterator it_2 = lt.begin();
		while (it_2 != lt.end())
		{
			//cout << (*it)._a1 << " ";
			cout << it_2->_a1 << " " << it_2->_a2 << endl;
			it_2++;
		}
	}
	void test_4()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		show(l1);

		auto rit = l1.rbegin();
		while (rit != l1.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;
	}


}